#!/usr/bin/env python
# coding: utf-8

import re
import os
import time
from onshs.ne.tnxxx.tnxxxcfg_basecase import *

class SbbUpgradeDowngradeSoftwaretn765(TnxxxCfg_BaseCase) :
    """
    SbbUpgradeDowngradeSoftwaretn765
    """
    OPTIONS = [
        {
            'opt' : '--cfgfile',
            'dest': 'cfgfile',
            'metavar' : 'PATH',
            'help' : 'the file of ip list configuration',
            'required' : False,
            'default' : "ip765.txt"
        },
    ]

    def get_iplist(self):
        iplist_filted = []
        if os.path.isfile(os.getcwd()+r'/'+ self.iplistfile):
            iplist = open(os.getcwd()+r'/'+ self.iplistfile)
        else:
            return iplist_filted

        for line in iplist:
            if re.match(r'^\s*$', line) is not None : continue # 忽略空白行
            if re.match(r'^\s*#', line) is not None : continue # 忽略注释行
            iplist_filted.append(line.strip('\n'))

        iplist.close()

        return iplist_filted

    def check_active_spct_ready(self, isactive):
        cmd_str = "configure terminal"
        self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), 0, CLI_PORT)
        cmd_str = "show active ppc"
        rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), 0, CLI_PORT)

        slotlist = re.findall("(\d+)", rtn_str)
        if slotlist != []:
            if isactive:
                cmd_str = "show card %d" % int(slotlist[0])
                rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), 0, CLI_PORT)

                if re.search(r"error", rtn_str) != None:
                    return False
                else:
                    return True
            else:
                cmd_str = "show card %d" % (23 - int(slotlist[0]))
                rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), 0, CLI_PORT)
                if re.search(r"error", rtn_str) != None:
                    return False
                else:
                    return True

    def disable_plugopen_int(self):
        if self.check_active_spct_ready(True):
            note_str = " Disable Plugopen Interrupt Slot <%d>?\n Input < y or n > :\n " % self.master_ppc
            disable_str = self.get_the_customer_input2(note_str)

            if disable_str == "Y":
                #BIT7为plug open中断掩码位
                cmd_str = r'*(0xa0000000+0x14*2)&=0xff7fffff'
                self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.master_ppc, DEV_PORT)

                cmd_str = r'(unsigned short)(*(0xa0000000+0x14*2))'
                rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.master_ppc, DEV_PORT)
                disable_intr =  int(re.findall("value = (\d+) =", rtn_str, re.I)[0])
                if (disable_intr&0x0080) == 0:
                    print "Close master spct's plug open interrupt success!\n"
        return True

    def enable_plugopen_int(self):
        if self.check_active_spct_ready(False):
            #1检查standby ppc的plug open中断掩码是否打开
            cmd_str = r'(unsigned short)(*(0xa0000000+0x14*2))'
            rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.slave_ppc, DEV_PORT)
            disable_intr =  int(re.findall("value = (\d+) =", rtn_str, re.I)[0])

            if (disable_intr & 0x0080) == 0:
                #standby ppc plugopen disable
                note_str = " Enable Plugopen Interrupt Slot <%d>? Input < y or n > :\n " % self.slave_ppc
                enable_str = self.get_the_customer_input2(note_str)

                if enable_str == "Y":
                    #检查plug open中断状态
                    cmd_str = r'(unsigned short)(*(0xa0000000+0x26*2))'
                    rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.slave_ppc, DEV_PORT)
                    disable_intr =  int(re.findall("value = (\d+) =", rtn_str, re.I)[0])
                    if (disable_intr | 0xfff9) == 0xffff:
                        cmd_str = r'(unsigned short)(*(0xa0000000+0x13*2))'
                        rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.slave_ppc, DEV_PORT)
                        his_intr =  int(re.findall("value = (\d+) =", rtn_str, re.I)[0])

                        if (his_intr | 0xff7f) == 0xffff:
                            # clear plug open intr
                            cmd_str = r'*(0xa0000000+0x26*2)&=0xffbfffff'
                            self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.slave_ppc, DEV_PORT)

                            cmd_str = r'*(0xa0000000+0x26*2)|=0x00400000'
                            self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.slave_ppc, DEV_PORT)

                            #BIT7为plug open中断掩码位
                            cmd_str = r'*(0xa0000000+0x14*2)|=0x00800000'
                            self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.slave_ppc, DEV_PORT)

                        cmd_str = r'(unsigned short)(*(0xa0000000+0x14*2))'
                        rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.slave_ppc, DEV_PORT)
                        disable_intr =  int(re.findall("value = (\d+) =", rtn_str, re.I)[0])
                        if (disable_intr|0xff7f) == 0xffff:
                            print "Open slave spct's plug open interrupt success!\n"
                    else:
                        print "Can't enable plugopen interrupt because of plug switch not close!\n"

            else:
                 print "Standby spct's plug open interrupt is already enable!\n"

        if self.check_active_spct_ready(True):
            #检查active ppc的中断mask是否打开
            cmd_str = r'(unsigned short)(*(0xa0000000+0x14*2))'
            rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.master_ppc, DEV_PORT)
            disable_intr =  int(re.findall("value = (\d+) =", rtn_str, re.I)[0])

            if (disable_intr & 0x0080) == 0:
                note_str = " Enable Plugopen Interrupt Slot <%d>? Input < y or n > :\n " % self.master_ppc
                enable_str = self.get_the_customer_input2(note_str)

                if enable_str == "Y":
                    #检查plug open中断状态
                    cmd_str = r'(unsigned short)(*(0xa0000000+0x26*2))'
                    rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.master_ppc, DEV_PORT)
                    disable_intr =  int(re.findall("value = (\d+) =", rtn_str, re.I)[0])
                    if (disable_intr | 0xfff9) == 0xffff:
                        cmd_str = r'(unsigned short)(*(0xa0000000+0x13*2))'
                        rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.master_ppc, DEV_PORT)
                        his_intr =  int(re.findall("value = (\d+) =", rtn_str, re.I)[0])

                        if (his_intr | 0xff7f) == 0xffff:
                            # clear plug open intr
                            cmd_str = r'*(0xa0000000+0x26*2)&=0xffbfffff'
                            self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.master_ppc, DEV_PORT)

                            cmd_str = r'*(0xa0000000+0x26*2)|=0x00400000'
                            self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.master_ppc, DEV_PORT)

                        #BIT7为plug open中断掩码位
                        cmd_str = r'*(0xa0000000+0x14*2)|=0x00800000'
                        self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.master_ppc, DEV_PORT)

                        cmd_str = r'(unsigned short)(*(0xa0000000+0x14*2))'
                        rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.master_ppc, DEV_PORT)
                        disable_intr =  int(re.findall("value = (\d+) =", rtn_str, re.I)[0])
                        if (disable_intr|0xff7f) == 0xffff:
                            print "Open master spct's plug open interrupt success!\n"
                    else:
                        print "Can't enable plugopen interrupt because of plug switch not close!\n"
            else:
                print "Master spct's plug open interrupt is already enable!\n"
            
        return True

    def check_plugopen_int(self):
        master_plug_open = "Not Ready"
        slave_plug_open = "Not Ready"

        if self.check_active_spct_ready(False):
            cmd_str = r'(unsigned short)(*(0xa0000000+0x14*2))'
            rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.slave_ppc, DEV_PORT)
            disable_intr =  int(re.findall("value = (\d+) =", rtn_str, re.I)[0])
            if (disable_intr&0x0080) == 0:
                slave_plug_open = "Stop"
            else:
                slave_plug_open = "Normal"

            if self.slave_ppc == 11:
                slot11 = "slot11: %s %s" % (slave_plug_open, "Slave")
            else:
                slot12 = "slot12: %s %s" % (slave_plug_open, "Slave")
        else:
            if self.check_active_spct_ready(True):
                if self.master_ppc == 12:
                    slot11 = "slot11: %s %s" % (slave_plug_open, "Slave")
                else:
                    slot12 = "slot12: %s %s" % (slave_plug_open, "Slave")

        if self.check_active_spct_ready(True):
            cmd_str = r'(unsigned short)(*(0xa0000000+0x14*2))'
            rtn_str = self.tnxxx.send_rtn_str(cmd_str, self.get_ne_ip(0), self.master_ppc, DEV_PORT)
            disable_intr =  int(re.findall("value = (\d+) =", rtn_str, re.I)[0])
            if (disable_intr&0x0080) == 0:
                master_plug_open = "Stop"
            else:
                master_plug_open = "Normal"

            if self.master_ppc == 11:
                slot11 = "slot11: %s %s" % (master_plug_open, "Master")
            else:
                slot12 = "slot12: %s %s" % (master_plug_open, "Master")

        print "Result:\n%s\n%s\n" % (slot11, slot12)

    def get_the_customer_input1(self, note):
        rtnstr  = raw_input(note)
        while True:
            if rtnstr.upper() in ["D","E","C","Q"]:
                break
            else:
                rtnstr  = raw_input(" Input < D or E or C or Q > :\n")

        return    rtnstr.upper()

    def get_the_customer_input2(self, note):
        rtnstr  = raw_input(note)
        while True:
            if rtnstr.upper() == "Y" or   rtnstr.upper() == "N":
                break
            else:
                rtnstr  = raw_input("Input < y or n > :\n")

        return    rtnstr.upper()

    def get_master_oam_and_ppc(self):
        rtn_str = None
        query_masteroam_cmd = r'show cfp status'
        rtn_str = self.tnxxx.send_rtn_str(r'configure terminal', self.get_ne_ip(0), 0, CLI_PORT)
        rtn_str = self.tnxxx.send_rtn_str(query_masteroam_cmd, self.get_ne_ip(0), 0, CLI_PORT)
        self.tnxxx.send_rtn_str(r'exit', self.get_ne_ip(0), 0, CLI_PORT)

        #有可能出现rtn_str无返回值的情况
        oam_list = re.findall(r'\\s=(\d+)\\c=(\d+)\r\nStatus: (\w+)', rtn_str)
        if [] == oam_list:
            return False
        else:
            for i in range(0,len(oam_list)):
                if oam_list[i][2] == "active" and (oam_list[i][0] == "21" or oam_list[i][0] == "22"):
                    self.master_oam = int(oam_list[i][0])
                elif oam_list[i][2] =="standby" and (oam_list[i][0] == "21" or oam_list[i][0] == "22"):
                    self.slave_oam = int(oam_list[i][0])
                elif oam_list[i][2] =="active" and (oam_list[i][0] == "11" or oam_list[i][0] == "12"):
                    self.master_ppc = int(oam_list[i][0])
                elif oam_list[i][2] =="standby" and (oam_list[i][0] == "11" or oam_list[i][0] == "12"):
                    self.slave_ppc = int(oam_list[i][0])
        return True

    def _execute(self):
        self.iplistfile = self.options.cfgfile
        ip_list = self.get_iplist()

        for ip in ip_list:
            self.set_ne_ip(0, ip)
            self.tnxxx.disconnect()
            self.get_master_oam_and_ppc()

            while True:
                note_str =  " Please select what you want to do!\n" \
                            " D:Disable plugopen interrupt.\n" \
                            " E:Enable plugopen interrupt.\n" \
                            " C:Check plugopen interrupt. \n" \
                            " Q:Quit script.\n" \
                            " Input < D or E or C or Q >"

                select_str = self.get_the_customer_input1(note_str)

                if select_str == "D":
                    self.disable_plugopen_int()
                elif select_str == "E":
                    self.enable_plugopen_int()
                elif select_str == "C":
                    self.check_plugopen_int()
                else:
                    return True
        return True

if __name__ == "__main__" :
    upgrade = SbbUpgradeDowngradeSoftwaretn765()
    upgrade.execute()
